﻿using SuperX.Common.Helper;
using SuperX.Common.Log;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Management;
using System.Net.NetworkInformation;
using System.Text;
using SuperX.Common.Collection;
using System.Threading.Tasks;
using Microsoft.Win32;
using Newtonsoft.Json;
using SuperX.Common.AppConfiguration;
using System.Net;
using System.Threading;

namespace SuperX.Common.OS
{
    public class WindowsCommand : OSCommand
    {
        private object _lockObj = new object();

        private string _prettyName;

        public static WindowsCommand GetNewWindowsCommand()
        {
            return new WindowsCommand();
        }

        #region 脚本执行

        public static string CMD(string command)
        {
            string result = string.Empty;
            using (System.Diagnostics.Process p = new System.Diagnostics.Process())
            {
                p.StartInfo.FileName = "cmd.exe";
                p.StartInfo.UseShellExecute = false;    //是否使用操作系统shell启动
                p.StartInfo.RedirectStandardInput = true;//接受来自调用程序的输入信息
                p.StartInfo.RedirectStandardOutput = true;//由调用程序获取输出信息
                p.StartInfo.RedirectStandardError = true;//重定向标准错误输出
                p.StartInfo.CreateNoWindow = true;//不显示程序窗口
                p.Start();//启动程序

                //向cmd窗口发送输入信息
                p.StandardInput.WriteLine(command + "&exit");

                p.StandardInput.AutoFlush = true;
                //p.StandardInput.WriteLine("exit");
                //向标准输入写入要执行的命令。这里使用&是批处理命令的符号，表示前面一个命令不管是否执行成功都执行后面(exit)命令，如果不执行exit命令，后面调用ReadToEnd()方法会假死
                //同类的符号还有&&和||前者表示必须前一个命令执行成功才会执行后面的命令，后者表示必须前一个命令执行失败才会执行后面的命令

                result = p.StandardOutput.ReadToEnd();//获取cmd窗口的输出信息
                p.WaitForExit();//等待程序执行完退出进程
                p.Close();
            }
            return result;
        }

        /// <summary>
        /// 执行windows下命令行
        /// 返回结果不包括输入的命令
        /// </summary>
        /// <param name="command"></param>
        /// <returns></returns>
        public static string CMD_ReturnWithoutCmd(string command)
        {
            string result = CMD(command);
            if (string.IsNullOrEmpty(result)) return result;

            int index = result.IndexOf("&exit");                      //输入的命令最后都以退出结束
            int removeLength = index + 5 + Environment.NewLine.Length;//要删除的字符串占的长度
            if (index <= 0 || result.Length < removeLength) return result;
            result = result.Remove(0, removeLength);
            return result;
        }

        public override string ScriptExecute(string content)
        {
            return CMD(content);
        }

        #endregion 脚本执行

        #region 路径

        public override string GetIoTDataDir()
        {
            return System.IO.Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName);//程序运行文件所在的文件夹
        }

        public override string GetGatewayOutputBaseDir()
        {
            return Path.Combine(SystemCfgService.GetInstance().SystemCfg.ProjectConfig.ProjectDirPath, "DownloadProject");
        }

        public override string GetGatewayBaseDir()
        {
            return GetSystemTmpDir();
        }

        public override string GetGatewayCurrentDir()
        {
            var currentFileFullName = Process.GetCurrentProcess().MainModule.FileName;
            var currentDir = Path.GetDirectoryName(currentFileFullName);
            return currentDir;
        }

        public override string GetLogDir()
        {
            var logPath = SystemCfgService.GetInstance().SystemCfg.LogConfig.LocalLogPath;
            return logPath;
        }

        public override string GetSystemTmpDir()
        {
            string tmpDirName = "IoTTmp";//临时文件夹名字
            var baseDir = GetIoTDataDir();
            return System.IO.Path.Combine(baseDir, tmpDirName);//本地存储的临时路径
        }

        #endregion 路径

        #region 信息统计

        public override double GetMemory(string processName)
        {
            PerformanceCounterCategory[] pcc = PerformanceCounterCategory.GetCategories();
            PerformanceCounter memoryCounter = null;
            for (int i = 0; i < pcc.Length; i++)
            {
                if (pcc[i].CategoryName == "Process")
                {
                    List<string> instanceNames = pcc[i].GetInstanceNames().ToList();
                    foreach (var instanceItemName in instanceNames)
                    {
                        if (instanceItemName == processName)
                        {
                            var countNames = pcc[i].GetCounters(instanceItemName).Select(m => m.CounterName);
                            if (countNames.Contains("Working Set - Private"))
                            {
                                memoryCounter = new PerformanceCounter("Process", "Working Set - Private", processName);
                            }
                            else if (countNames.Contains("Working Set"))
                            {
                                memoryCounter = new PerformanceCounter("Process", "Working Set", processName);
                            }
                            break;
                        }
                    }
                    break;
                }
            }
            if (memoryCounter == null)
                return double.NaN;
            var usedMemory = memoryCounter.NextValue() / 1024 / 1024;//
            return usedMemory;
        }

        public override double GetCpu(string processName)
        {
            PerformanceCounter thecpuCounter = new PerformanceCounter("Process", "% Processor Time", processName);
            // 初始值为 0，需要等待一段时间才能获取准确的 CPU 使用情况
            thecpuCounter.NextValue();
            Thread.Sleep(500);
            float cpuUsage = thecpuCounter.NextValue();
            return cpuUsage;
        }

        public override string GetOSDescription()
        {
            //TODO:
            return string.Empty;
        }

        public override DateTime GetGatewayStartTime()
        {
#if NET40 || NET45 || NET461
            EventLog MySystemEvent = new EventLog();
            //说明这个日志是系统日志
            MySystemEvent.Log = "System";
            //获得日志的记录集合
            EventLogEntryCollection MyEventCollection = MySystemEvent.Entries;
            var list = new List<EventLogEntry>();
            var events = MyEventCollection.GetEnumerator();
            while (events.MoveNext())
            {
                var currentEvent = (EventLogEntry)events.Current;
                if (currentEvent != null && currentEvent.EventID == 6005)
                {
                    list.Add(currentEvent);
                }
            }
            list.Reverse();
            var lastStart = list.FirstOrDefault();
            var time = lastStart == null ? DateTime.MinValue : lastStart.TimeGenerated;
            return time;
#else
            return DateTime.MinValue;
#endif
        }

        public override List<string> GetNetAdapterMacAddress()
        {
            ManagementObjectSearcher searcher = new ManagementObjectSearcher
    ("Select MACAddress,PNPDeviceID FROM Win32_NetworkAdapter WHERE MACAddress IS NOT NULL AND PNPDeviceID IS NOT NULL");
            ManagementObjectCollection mObject = searcher.Get();

            var list = new List<string>();
            foreach (ManagementObject obj in mObject)
            {
                string pnp = obj["PNPDeviceID"].ToString();
                if (pnp.Contains("PCI\\"))
                {
                    string mac = obj["MACAddress"].ToString();
                    mac = mac.Replace(":", string.Empty);
                    list.Add(mac);
                }
            }
            list.AddRange(GetAllNetworkMacAddresses() ?? new List<string>());
            return list;
        }

        /// <summary>
        /// 获取指定ip的NetworkInterface
        /// </summary>
        /// <param name="ip"></param>
        /// <returns></returns>
        private NetworkInterface GetTargetNetworkInterface(string ip)
        {
            return NetworkInterface.GetAllNetworkInterfaces().FirstOrDefault(adapter =>
            {
                IPInterfaceProperties property = adapter.GetIPProperties();

                foreach (UnicastIPAddressInformation ipInfo in property.UnicastAddresses)
                {
                    if (ipInfo.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
                    {
                        if (ipInfo.Address?.ToString() == ip)
                        {
                            return true;
                        }
                    }
                }
                return false;
            });
        }

        private List<string> GetAllNetworkMacAddresses()
        {
            IPGlobalProperties computerProperties = IPGlobalProperties.GetIPGlobalProperties();
            NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces();
            if (nics == null || nics.Length < 1)
            {
                Console.WriteLine("No network interfaces found.");
                return null;
            }
            var result = new List<string>();
            foreach (NetworkInterface adapter in nics)
            {
                if (adapter.NetworkInterfaceType == NetworkInterfaceType.Loopback) continue;
                IPInterfaceProperties properties = adapter.GetIPProperties(); //  .GetIPInterfaceProperties();
                PhysicalAddress address = adapter.GetPhysicalAddress();
                byte[] bytes = address.GetAddressBytes();
                var currentMacAddress = string.Empty;
                for (int i = 0; i < bytes.Length; i++)
                {
                    currentMacAddress += bytes[i].ToString("x2");
                }
                result.Add(currentMacAddress);
            }
            return result;
        }

        public override string GetMotherBoardID()
        {
            try
            {
                ManagementClass mc = new ManagementClass("Win32_BaseBoard");
                ManagementObjectCollection moc = mc.GetInstances();
                string strID = null;
                foreach (ManagementObject mo in moc)
                {
                    strID = mo.Properties["SerialNumber"].Value.ToString();
                    break;
                }
                return strID;
            }
            catch
            {
                return "unknown";
            }
        }

        public override string GetCpuID()
        {
            try
            {
                string strCpuID = string.Empty;
                ManagementClass mc = new ManagementClass("Win32_Processor");
                ManagementObjectCollection moc = mc.GetInstances();
                foreach (ManagementObject mo in moc)
                {
                    strCpuID = mo.Properties["ProcessorId"].Value.ToString();
                }
                moc = null;
                mc = null;
                return strCpuID;
            }
            catch
            {
                return "unknown";
            }
        }

        public override List<string> GetHardwareInfo()
        {
            return null;
        }

        #endregion 信息统计

        #region 进程管理

        public override void StartBrowser(string uri)
        {
            //System.Diagnostics.Process.Start("explorer.exe", uri);
            try
            {
                System.Diagnostics.Process.Start(uri);
            }
            catch (System.ComponentModel.Win32Exception noBrowser)
            {
                Logger.Warn(noBrowser.Message);
            }
            catch (System.Exception other)
            {
                Logger.Warn(other.Message);
            }
        }

        public override List<Process> GetProcesses(string processName)
        {
            return Process.GetProcessesByName(processName).ToList();
        }

        public override void StartProcess(string fileFullPathName)
        {
            //执行启动
            System.Diagnostics.ProcessStartInfo info = new System.Diagnostics.ProcessStartInfo();
            info.FileName = fileFullPathName.Replace(@"\", "/");
            info.WorkingDirectory = Path.GetDirectoryName(fileFullPathName);
            System.Diagnostics.Process proc;
            try
            {
                Logger.Info(string.Format("{0}  启动进程{1}", DateTime.Now, fileFullPathName));
                proc = System.Diagnostics.Process.Start(info);
            }
            catch (Exception ex)
            {
                Logger.Warn(string.Format("{0}  启动{1}出现异常", DateTime.Now, fileFullPathName));
                Logger.Exception(ex);
            }
        }

        public override void ExitSelfProcess(string processName = null)
        {
            Environment.Exit(0);
        }

        public override void GatewayRestart(string fileFullPathName, string reason, string processName)
        {
            ProcessManagerReStartProcess(fileFullPathName);
        }

        public override void MonitorHelperStopProcess(string processName, string reason, string serviceName)
        {
            StopProcess(processName, reason);
        }

        public override void MonitorHelperStartProcess(string processName, string reason, string serviceName)
        {
            ProcessManagerStartProcess(processName);
        }

        #endregion 进程管理

        public override void CheckOtherUpdate(InvokeMsg invokeMessage)
        {
            //空实现即可，只在Linux环境下需要
        }

        #region IP管理

        public override Tuple<bool, bool, List<string>> GetAutoAndDns(string adapterName, IPInterfaceProperties property, string ipv4)
        {
            var IsDHCP = property.DhcpServerAddresses?.Count != 0 ? true : false;
            var regisIpv4Key = IsDHCP ? "DhcpIPAddress" : "IPAddress";
            var DnsAuto = GetWindowsDnsStatus(ipv4, regisIpv4Key);
            var Dns = new List<string>();
            foreach (IPAddress dnsAddresse in property.DnsAddresses)//获取域名
            {
                var addrStr = dnsAddresse?.ToString();
                Dns.Add(addrStr);
            }
            return new Tuple<bool, bool, List<string>>(IsDHCP, DnsAuto, Dns);
        }

        /// <summary>
        /// 获取windows下dns是否是自动的状态
        /// </summary>
        /// <param name="ipIndetify"></param>
        /// <param name="regisIpv4Key"></param>
        /// <returns></returns>
        private bool GetWindowsDnsStatus(string ipIndetify, string regisIpv4Key)
        {
#if NET40 || NET45 || NET461
            if (string.IsNullOrEmpty(ipIndetify))
            {
                return false;
            }

            RegistryKey root = Registry.LocalMachine;
            var adapterNames = root.OpenSubKey("SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces").GetSubKeyNames();//获取注册表所有的网卡名
            foreach (var item in adapterNames)
            {
                var ipv4 = Regedit.GetRegistryValue($"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\{item}", $"{regisIpv4Key}");
                if (ipv4 == null)
                {
                    continue; //判断是不是当前的网卡
                }

                if (ipv4 is string str)
                {
                    if (ipIndetify == str)
                    {
                        var dnsIp = Regedit.GetRegistryValue($"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\{item}", "NameServer");
                        return string.IsNullOrEmpty(dnsIp as string);
                    }
                }
                else if (ipv4 is string[] ipArray)
                {
                    if (ipArray.Length != 0 && ipIndetify == ipArray[0])
                    {
                        var dnsIp = Regedit.GetRegistryValue($"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\{item}", "NameServer");
                        return string.IsNullOrEmpty(dnsIp as string);
                    }
                }
            }
#endif
            return false;
            //#else

            //#endif
        }

        public override bool SetIPAddress(string ip, string editIp, string submask, string gateway, string[] dns, bool dnsAuto, bool dchpAuto, string mac)
        {
            if (string.IsNullOrWhiteSpace(mac) && !string.IsNullOrWhiteSpace(ip))
            {
                var networkInterface = GetTargetNetworkInterface(ip);
                mac = networkInterface?.GetPhysicalAddress().ToString();
            }
            if (string.IsNullOrWhiteSpace(mac))
            {
                Logger.Error($"无法找到指定IP {ip}的网卡接口");
                return false;
            }
            return SetIPAddress(ip, new string[] { editIp }, new string[] { submask }, new string[] { gateway }, dns, dnsAuto, dchpAuto, mac);
        }

        /// <summary>
        /// 设置IP地址，掩码，服务节点和DNS
        /// </summary>
        /// <param name="ip"></param>
        /// <param name="submask"></param>
        /// <param name="getway"></param>
        /// <param name="dns"></param>
        private static bool SetIPAddress(string ipIdentify, string[] ip, string[] submask, string[] getway, string[] dns, bool dnsAuto, bool dchpAuto, string macAddress)
        {
            var reslut = false;
            ManagementClass wmi = new ManagementClass("Win32_NetworkAdapterConfiguration");
            ManagementObjectCollection moc = wmi.GetInstances();
            ManagementBaseObject inPar = null;
            ManagementBaseObject outPar = null;
            try
            {
                foreach (ManagementObject mo in moc)
                {
                    //如果没有启用IP设置的网络设备则跳过
                    //if (!(bool)mo["IPEnabled"])
                    //    continue;
                    var macData = mo.Properties["MACAddress"];
                    if (macData == null || string.IsNullOrWhiteSpace(Convert.ToString(macData.Value)) || macAddress != Convert.ToString(macData.Value))
                    {
                        continue;
                    }
                    //设置指定IP地址网卡的IP地址和掩码
                    if (ip != null && submask != null && !dchpAuto)
                    {
                        inPar = mo.GetMethodParameters("EnableStatic");
                        inPar["IPAddress"] = ip;
                        inPar["SubnetMask"] = submask;
                        outPar = mo.InvokeMethod("EnableStatic", inPar, null);
                    }

                    //设置服务节点地址
                    if (getway != null && !dchpAuto)
                    {
                        inPar = mo.GetMethodParameters("SetGateways");
                        inPar["DefaultIPGateway"] = getway;
                        outPar = mo.InvokeMethod("SetGateways", inPar, null);
                    }
                    if (dnsAuto)
                    {
                        mo.InvokeMethod("SetDNSServerSearchOrder", null);
                    }
                    else
                    {
                        //设置DNS地址
                        if (dns != null)
                        {
                            inPar = mo.GetMethodParameters("SetDNSServerSearchOrder");
                            inPar["DNSServerSearchOrder"] = dns;
                            outPar = mo.InvokeMethod("SetDNSServerSearchOrder", inPar, null);
                        }
                    }

                    break;
                }

                reslut = true;
            }
            catch (Exception ex)
            {
                Logger.Warn(ex.Message);
                return reslut;
            }
            return reslut;
        }

        public override bool EnableDHCP(string name, string identifyIp, bool dnsAuto, string[] dnsArray)
        {
            var reslut = false;
            try
            {
                ManagementClass wmi = new ManagementClass("Win32_NetworkAdapterConfiguration");
                ManagementObjectCollection moc = wmi.GetInstances();
                foreach (ManagementObject mo in moc)//有bug
                {
                    //如果没有启用IP设置的网络设备则跳过
                    //if (!(bool)mo["IPEnabled"])
                    //    continue;
                    var parames = mo["IPAddress"];
                    if (parames == null || (parames as string[])[0] != identifyIp)
                        continue;
                    //开启DHCP
                    mo.InvokeMethod("EnableDHCP", null);
                    //重置DNS为空
                    if (dnsAuto)
                    {
                        mo.InvokeMethod("SetDNSServerSearchOrder", null);
                    }
                    else
                    {
                        if (dnsArray != null)
                        {
                            ManagementBaseObject inPar = null;
                            ManagementBaseObject outPar = null;
                            inPar = mo.GetMethodParameters("SetDNSServerSearchOrder");
                            inPar["DNSServerSearchOrder"] = dnsArray;
                            outPar = mo.InvokeMethod("SetDNSServerSearchOrder", inPar, null);
                        }
                    }
                }
                reslut = true;
            }
            catch (Exception ex)
            {
                Logger.Warn(ex.Message);
                reslut = false;
            }
            return reslut;
        }

        #endregion IP管理

        #region 更新程序

        public const string UpdateSoftwareTmpDirName = "UpdateSoftwareTmp";//放置更新文件的临时文件夹名

        public const string BatchFileName_Windows = "UpdateSoftware.bat";  //windows批处理文件文件名

        /// <summary>
        /// 开始更新
        /// </summary>
        public override void StartUpdate(string updateSoftwareTmpDir, string subDir)
        {
            try
            {
                var updateSoftwareInfo = new UpdateSoftwareInfo
                {
                    UpdateSoftwareTmpDir = updateSoftwareTmpDir,
                    SubDir = subDir
                };
                GenerateUpdateBat_Windows(updateSoftwareInfo);
                ExecuteBatFile_Windows(updateSoftwareInfo);
            }
            catch (Exception ex)
            {
                Logger.Exception(ex);
            }
        }

        /// <summary>
        /// 生成windows下的批处理文件
        /// </summary>
        private void GenerateUpdateBat_Windows(UpdateSoftwareInfo updateSoftwareInfo)
        {
            List<string> batchContents = new List<string>();
            string batFilePath = Path.Combine(updateSoftwareInfo.SubDir, BatchFileName_Windows);

            string currentRunningDir = Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName);//程序运行文件所在的文件夹

            #region 生成批处理里面文件的内容

            if (CheckExistInstaller(updateSoftwareInfo))                            //存在安装文件，则先卸载，再安装
            {
                //batchContents.Add("copy  \"" + Path.Combine(currentRunningDir, "UpdateSoftware.exe") + "\"  \"" + _subDir + "\"  /y");//拷贝启动运行时的程序到更新目录，安装或者更新完成后调用启动运行时
                //string installerFullPath = Path.Combine(_subDir, InstallerName_Windows);
                ////batchContents.Add("wmic product where caption=\"IoT\" call uninstall");
                //batchContents.Add("FOR /f \"tokens=1\" %%i in ('reg query \"HKEY_LOCAL_MACHINE\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\" /s /d /f \"IoT_\"^|FINDSTR /i \"CurrentVersion\"') do (FOR /f \"tokens=1-2,*\" %%j in ('reg query \"%%i\" /f \"UninstallString\"^|FINDSTR /i \"UninstallString\"') do (CMD /q /c \"%%l\"))");
                //batchContents.Add("\""+installerFullPath + "\" /quiet");
                //batchContents.Add("start \"\" \"" + Path.Combine(_subDir, "UpdateSoftware.exe")+"\""); //调用启动运行时的程序
                ProcessManagerStartProcess(Path.Combine(updateSoftwareInfo.SubDir, "UpdateSoftware.exe"));//调用启动更新的程序
                return;
            }
            else                                                  //不存在安装文件，则只是文件或者dll的更新
            {
                batchContents.Add("taskkill /im IoTServiceNet45.exe /f");     //结束开发时
                batchContents.Add("taskkill /im ListenerService.exe /f");//结束监听程序

                //获取更新的软件信息
                GetUpdateSoftwareInfo(currentRunningDir, updateSoftwareInfo);
                if (updateSoftwareInfo == null)
                {
                    Logger.Warn(nameof(updateSoftwareInfo) + " is null,return");
                    return;
                }

                if (updateSoftwareInfo != null && updateSoftwareInfo.FileNameAndRelativePaths?.Count > 0)
                {
                    foreach (var item in updateSoftwareInfo.FileNameAndRelativePaths)
                    {
                        string sourceFilePath = Path.Combine(updateSoftwareInfo.SubDir, item.Key);            //拼接源路径+文件名
                        string desPath = Path.Combine(currentRunningDir, item.Value);    //拼接目标文件夹

                        batchContents.Add("copy  \"" + sourceFilePath + "\"  \"" + desPath + "\"  /y");//路径加上双引号
                    }
                }
                batchContents.Add("start \"\" \"" + Path.Combine(currentRunningDir, "IoTServiceNet45.exe") + "\""); //调用启动运行时
            }
            batchContents.Add("ping 12.12.12.12");                                          //作为延时
            batchContents.Add("rd /s /q \"" + updateSoftwareInfo.SubDir + "\"");                              //删除临时放置更新文件的文件夹
            batchContents.Add("exit");

            #endregion 生成批处理里面文件的内容

            //写到批处理文件
            WriteTxtToFile(batchContents, batFilePath, updateSoftwareInfo);
        }

        /// <summary>
        /// 执行批处理文件
        /// </summary>
        private void ExecuteBatFile_Windows(UpdateSoftwareInfo updateSoftwareInfo)
        {
            Process proc = null;
            try
            {
                string targetDir = updateSoftwareInfo.SubDir;//string.Format(@"c:\adapters\setup");//this is where selftBatch.bat lies
                proc = new Process();
                proc.StartInfo.WorkingDirectory = targetDir;
                proc.StartInfo.FileName = BatchFileName_Windows;
                proc.StartInfo.Arguments = string.Format("10");//this is argument
                proc.StartInfo.CreateNoWindow = false;
                proc.Start();
                proc.WaitForExit();
            }
            catch (Exception ex)
            {
                Logger.WarnException(ex);
            }
        }

        /// <summary>
        /// 检查是否存在安装文件
        /// </summary>
        private bool CheckExistInstaller(UpdateSoftwareInfo updateSoftwareInfo)
        {
            string[] files = Directory.GetFiles(updateSoftwareInfo.SubDir);//得到文件
            foreach (string file in files)            //循环文件
            {
                string exname = file.Substring(file.LastIndexOf(".") + 1);//得到后缀名

                if (CheckIsWinsInstaller(file))
                {
                    Path.GetFileName(file);//获取windows安装包名字
                    return true;//Windows下安装包
                }
            }
            return false;
        }

        /// <summary>
        /// 获取需要更新的软件信息
        /// </summary>
        private void GetUpdateSoftwareInfo(string currentRunningDir, UpdateSoftwareInfo updateSoftwareInfo)
        {
            string filePath = Path.Combine(updateSoftwareInfo.SubDir, "UpdateSoftwareInfo.cfg"); //配置文件
            if (File.Exists(filePath))
            {
                var result = JsonHelper.JsonDeserializeFromFile(filePath, typeof(UpdateSoftwareInfo), Encoding.UTF8) as UpdateSoftwareInfo;
                updateSoftwareInfo.FileNameAndRelativePaths = result.FileNameAndRelativePaths;
            }
            else
            {
                //没有配置文件，则查询以前的dll等文件是放在哪个目录下的
                //以前放哪里，更新的仍然放在对应的地方，如果没有，则默认加在运行的根目录
                //updateSoftwareInfo = new UpdateSoftwareInfo();
                GetRunFileInfos(currentRunningDir, currentRunningDir);//先获取原有dll等放置的相对路径

                //遍历放置有更新文件的临时文件夹，获取对应文件信息
                DirectoryInfo Dir = new DirectoryInfo(updateSoftwareInfo.SubDir);
                foreach (FileInfo f in Dir.GetFiles())                             //查找文件
                {
                    if (_runfilesInfos.ContainsKey(f.Name))
                    {
                        updateSoftwareInfo.FileNameAndRelativePaths.Add(f.Name, _runfilesInfos[f.Name]);
                    }
                    else
                    {
                        updateSoftwareInfo.FileNameAndRelativePaths.Add(f.Name, string.Empty);
                    }
                }
            }
        }

        /// <summary>
        /// 写信息到文本
        /// </summary>
        /// <param name="contents">要写的内容</param>
        /// <param name="batFilePath">文件名字路径</param>
        private void WriteTxtToFile(List<string> contents, string batFilePath, UpdateSoftwareInfo updateSoftwareInfo)
        {
            Logger.Info("批处理文件路径：" + batFilePath);
            if (contents == null || contents.Count <= 0) return;
            FileStream fs = new FileStream(batFilePath, FileMode.OpenOrCreate, FileAccess.Write);
            StreamWriter sw = new StreamWriter(fs, Encoding.Default);

            foreach (var item in contents)
            {
                sw.WriteLine(item);//生成批处理里面文件的内容
            }

            sw.Flush();
            sw.Close();
            fs.Close();
            fs.Dispose();
        }

        /// <summary>
        /// 程序运行目录下的文件信息
        /// Key：文件名，Value：相对于运行目录的相对路径。
        /// 用于更新dll等之类时，进行比对。
        /// </summary>
        private Dictionary<string, string> _runfilesInfos = new Dictionary<string, string>();

        /// <summary>
        /// 递归获取程序运行文件夹下的文件信息和子文件夹信息
        /// </summary>
        /// <param name="searchDirPath">要搜索的文件夹路径</param>
        /// <param name="runDirPath">运行目录的路径</param>
        private void GetRunFileInfos(string searchDirPath, string runDirPath)
        {
            if (string.IsNullOrEmpty(searchDirPath)) return;
            if (string.IsNullOrEmpty(runDirPath)) return;
            if (Directory.Exists(searchDirPath) && Directory.Exists(GetSystemTmpDir()))
            {
                if (new DirectoryInfo(searchDirPath).Name == new DirectoryInfo(GetSystemTmpDir()).Name)
                {
                    //Logger.Info($"搜索到临时路径，跳过!路径：{searchDirPath}");
                    return;//临时路径，不作为记录
                }
            }
            searchDirPath = searchDirPath.Replace(@"\", "/");                //替换为统一的路径符号
            runDirPath = runDirPath.Replace(@"\", "/");

            searchDirPath = searchDirPath.Replace("//", "/");                 //替换为单“/”，便于下面截取字符串获取准确长度
            runDirPath = runDirPath.Replace("//", "/");

            //在指定目录及子目录下查找文件,在list中列出子目录及文件
            DirectoryInfo Dir = new DirectoryInfo(searchDirPath);

            //获取当前目录的文件信息
            foreach (FileInfo f in Dir.GetFiles())                             //查找文件
            {
                string relativeDir = string.Empty;
                if (searchDirPath != runDirPath)
                {
                    relativeDir = searchDirPath.Substring(runDirPath.Length + 1);//当前搜索的目录与运行的目录不相等，则要截取出当前搜索目录相对于运行目录的相对路径
                }
                if (!_runfilesInfos.ContainsKey(f.Name))
                {
                    _runfilesInfos.Add(f.Name, relativeDir);                   //加到文件信息字典中
                }
            }
            //查找子目录，递归
            DirectoryInfo[] DirSub = Dir.GetDirectories();
            if (DirSub?.Length > 0)
            {
                foreach (DirectoryInfo d in DirSub)
                {
                    GetRunFileInfos(d.FullName, runDirPath);
                }
            }
        }

        /// <summary>
        /// 检查是否是windows安装包
        /// </summary>
        /// <param name="fileName">全路径</param>
        /// <returns></returns>
        public static bool CheckIsWinsInstaller(string fileName)
        {
            if (!string.IsNullOrEmpty(fileName) && fileName.ToLower().EndsWith(".exe"))
            {
                System.Diagnostics.FileVersionInfo fileVersionInfo = System.Diagnostics.FileVersionInfo.GetVersionInfo(fileName);
                if (fileVersionInfo != null && !string.IsNullOrEmpty(fileVersionInfo.ProductName)
                    && fileVersionInfo.ProductName.Contains("IoT"))
                {
                    return true;//Windows下安装包
                }
            }
            return false;
        }

        #endregion 更新程序

        public override string FormatDirectorySeparatorChar(string content)
        {
            return content;
        }

        #region 共享文件夹

        /// <summary>
        /// 创建挂载路径
        /// </summary>
        /// <param name="dirPath">挂载路径</param>
        public override void CreateMountDir(string dirPath)
        {
        }

        /// <summary>
        /// 移除挂载路径
        /// </summary>
        /// <param name="dirPath">挂载的路径</param>
        public override void RemoveMountDir(string dirPath)
        {
        }

        /// <summary>
        /// 删除文件夹
        /// </summary>
        /// <param name="dirPath">路径</param>
        public override void DeleteDir(string dirPath)
        {
            if (string.IsNullOrEmpty(dirPath)) return;
            if (!Directory.Exists(dirPath)) return;
            Directory.Delete(dirPath, true);
        }

        #endregion 共享文件夹

        public override bool IsSupportIPManager()
        {
            return true;
        }

        public override FunctionState GetSSHServerState()
        {
            return FunctionState.NotFound;
        }

        public override void RestartSSHServer()
        {
        }
    }
}